package com.leafrest.core.aspect;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;

import com.leafrest.core.RestBaseController;
import com.leafrest.core.annotation.Param;
import com.leafrest.core.annotation.Param.type;
import com.leafrest.core.annotation.ParamValidater;
import com.leafrest.core.constant.ErrorCode;
import com.leafrest.core.utils.RegexUtils;
import com.leafrest.core.utils.TypeUtils;

/**
 * 自定义参数验证注解切面拦截器
 * 
 * @author 李欢
 *
 */
public class ParamValidateAspect extends RestBaseController {

	public Object validate(ProceedingJoinPoint pjp) throws Throwable {
		try {
			if (pjp.getArgs() != null && pjp.getArgs().length > 0) {
				Signature sig = pjp.getSignature();
				if (!(sig instanceof MethodSignature)) {
					throw new IllegalArgumentException("该注解只能用于方法");
				}
				MethodSignature msig = (MethodSignature) sig;
				Object target = pjp.getTarget();
				Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
				ParamValidater validater = currentMethod.getAnnotation(ParamValidater.class);
				if (validater != null && pjp.getArgs().length > 0) {
					HttpServletRequest request = (HttpServletRequest) pjp.getArgs()[0];
					for (Param param : validater.parameters()) {
						String value = request.getParameter(param.name());
						// 判断参数是否要求必填，并判断参数是否为空
						if ((param.require() || param.minLength() != -1 || param.maxLength() != -1)
								&& StringUtils.isEmpty(value)) {
							return createResults(ErrorCode.PARAMTER_REQUIRE.setArgs(param.name()));
						}
						// 判断参数是否要验证最小长度，并判断参数是否满足最小长度限制
						if (param.minLength() != -1 && value.length() < param.minLength()) {
							return createResults(ErrorCode.PARAMTER_TOO_SHORT.setArgs(param.name(), value.length()));
						}
						// 判断参数是否要验证最大长度，并判断参数是否满足最大长度限制
						if (param.maxLength() != -1 && value.length() > param.maxLength()) {
							return createResults(ErrorCode.PARAMTER_TOO_LONG.setArgs(param.name(), value.length()));
						}
						// 判断参数类型，并判断参数是否是对应的类型
						if (param.type() == type.INTEGER && !TypeUtils.isInt(value)) {// 是否是整型
							return createResults(ErrorCode.PARAMTER_FORMAT_ILLEGAL.setArgs(param.name(), type.INTEGER));
						} else if (param.type() == type.BOOLEAN && !TypeUtils.isBoolean(value)) {// 是否是布尔型
							return createResults(ErrorCode.PARAMTER_FORMAT_ILLEGAL.setArgs(param.name(), type.BOOLEAN));
						} else if (param.type() == type.DATE && !TypeUtils.isDate(value)) {// 是否是日期类型
							return createResults(ErrorCode.PARAMTER_FORMAT_ILLEGAL.setArgs(param.name(), type.DATE));
						} else if (param.type() == type.DOUBLE && !TypeUtils.isDouble(value)) {// 是否是double浮点类型
							return createResults(ErrorCode.PARAMTER_FORMAT_ILLEGAL.setArgs(param.name(), type.DOUBLE));
						} else if (param.type() == type.FLOAT && !TypeUtils.isFloat(value)) {// 是否是float浮点类型
							return createResults(ErrorCode.PARAMTER_FORMAT_ILLEGAL.setArgs(param.name(), type.FLOAT));
						} else if (param.type() == type.LONG && !TypeUtils.isLong(value)) {// 是否是长整型
							return createResults(ErrorCode.PARAMTER_FORMAT_ILLEGAL.setArgs(param.name(), type.LONG));
						} else if (param.type() == type.EMAIL && !RegexUtils.checkEmail(value, 50)) {// 是否是合法的email类型
							return createResults(ErrorCode.PARAMTER_FORMAT_ILLEGAL.setArgs(param.name(), type.EMAIL));
						} else if (param.type() == type.MOBILE && !RegexUtils.checkMobile(value)) {// 是否是合法的手机号类型
							return createResults(ErrorCode.PARAMTER_FORMAT_ILLEGAL.setArgs(param.name(), type.MOBILE));
						} else if (StringUtils.isNotEmpty(param.regex()) && !value.matches(param.regex())) {// 自定义正则表达式验证
							return createResults(ErrorCode.CUSTOM.setCode(param.error().code()).setMsg(param.error().msg()));
						}
					}
				}
			}
			return pjp.proceed();// 执行原方法
		} catch (RuntimeException e) {
			e.printStackTrace();
			return createResults(ErrorCode.INTERNAL_ERROR);
		}
	}

}
